package cn.lili.controller.user;

import cn.hutool.core.collection.CollectionUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.member.service.ManagerUserService;
import cn.lili.modules.member.service.VipApplyService;
import cn.lili.modules.member.service.VipCodeService;
import cn.lili.modules.system.entity.dos.LiVipActiveCode;
import cn.lili.modules.system.entity.dos.LiVipApply;
import cn.lili.modules.system.entity.dos.UserPageDto;
import cn.lili.modules.system.entity.dto.ApplyCodeDto;
import cn.lili.modules.system.entity.dto.VipApplyCheck;
import cn.lili.modules.system.entity.dto.VipCodeDto;
import cn.lili.modules.urbansubstation.client.UrbanSubstationClient;
import cn.lili.modules.urbansubstation.entity.dos.UrbanSubstation;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user/vip")
@Api(tags = "会员激活码接口")
public class VipCodeController {
    @Autowired
    private VipCodeService codeService;
    @Autowired
    private ManagerUserService userService;
    @Autowired
    private VipApplyService applyService;
    @Autowired
    private UrbanSubstationClient urbanSubstationClient;

    @ApiOperation(value = "会员激活码生成")//
    @GetMapping("/vipCode")       //路径暂定,涉及权限表资源
    //获取前端传递过来的供应商id与需要生成的激活码数量
    public ResultMessage<Object> getVipCode(Integer num, String supplierId, Integer mouthNum){
        //判断数量是否正确
        if (num==null||num<0||StringUtils.isEmpty(supplierId)||mouthNum==null||mouthNum<0)
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        if (num>1000)
            num=1000;
        //判断供应商存不存在,查询user库的user表scene为supplier的该id存不存在
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.and(q -> q.eq(User::getExtendId, supplierId).or().eq(User::getId, supplierId));
        lambdaQueryWrapper.last("limit 1");

        User user = userService.getBaseMapper().selectOne(lambdaQueryWrapper);

        UrbanSubstation urbanSubstation = urbanSubstationClient.getUrbanSubstation(supplierId);

        if (Objects.isNull(urbanSubstation)){
            throw new ServiceException("未找到该城市站点");
        }

        if (Objects.isNull(user)|| !SceneEnums.URBAN_SUBSTATION.name().equals(user.getScene()))
            throw new ServiceException(ResultCode.URBAN_NOT_EXIST);

        user.setUsername(urbanSubstation!=null ? urbanSubstation.getUrbanName() : null);
        //批量生成激活码
        ArrayList<LiVipActiveCode> codes = new ArrayList<>();
        getCodes(num,user,mouthNum,codes);
        codeService.saveBatch(codes);

        return ResultUtil.success();
    }

    @ApiOperation(value = "城市站点列表")
    @GetMapping("/urbanList")
    public ResultMessage<Object> UrbanList(UserPageDto dto){
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(User::getEnable,1)
                .like(StringUtils.isNotEmpty(dto.getUserName()),User::getUsername,dto.getUserName())
                .like(StringUtils.isNotEmpty(dto.getNickName()),User::getNickName,dto.getNickName())
                .like(StringUtils.isNotEmpty(dto.getMobile()),User::getMobile,dto.getMobile())
                .eq(User::getScene,dto.getScene())
                .eq(Objects.nonNull(dto.getSex()),User::getSex,dto.getSex());

        return ResultUtil.data(userService.page(new Page<>(dto.getPageNumber(),dto.getPageSize()),wrapper));
    }

    @ApiOperation(value = "查询激活码")
    @GetMapping("/find")
    public ResultMessage<Object> findVipCode(VipCodeDto dto){
        LambdaQueryWrapper<LiVipActiveCode> wrapper=new LambdaQueryWrapper<LiVipActiveCode>();
        wrapper.like(!StringUtils.isEmpty(dto.getActiveCode()),LiVipActiveCode::getActiveCode,dto.getActiveCode())
                .orderByDesc(LiVipActiveCode::getCreateTime)
                .eq(StringUtils.isNotEmpty(dto.getSupplierId()),LiVipActiveCode::getSupplierId,dto.getSupplierId())
            .like(!StringUtils.isEmpty(dto.getSupplierName()),LiVipActiveCode::getSupplierName,dto.getSupplierName())
                .eq(dto.getActiveStatus()!=null,LiVipActiveCode::getActiveStatus,dto.getActiveStatus());
        Page<LiVipActiveCode> page = new Page<>(dto.getPageNumber(),dto.getPageSize());

        Page<LiVipActiveCode> page1 = codeService.page(page, wrapper);
        this.findVipCodeConversion(page1);
        return ResultUtil.data(page1);
    }

    private void findVipCodeConversion(Page<LiVipActiveCode> page1) {
        if (CollectionUtil.isEmpty(page1.getRecords())) {
            return;
        }
        List<String> userIdList = page1.getRecords().stream().map(LiVipActiveCode::getUserId).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(userIdList)) {
            List<User> userList = userService.list(new LambdaQueryWrapper<User>().in(User::getId, userIdList));
            if (CollectionUtil.isNotEmpty(userList)) {
                for (LiVipActiveCode liVipActiveCode : page1.getRecords()) {
                    for (User user : userList) {
                        if (user.getId().equals(liVipActiveCode.getUserId())) {
                            liVipActiveCode.setUserName(user.getUsername());
                        }
                    }
                }
            }
        }
    }

    @ApiOperation(value = "申请激活码分页")
    @GetMapping("/apply")
    public ResultMessage<Object> vipApply(ApplyCodeDto dto){
        LambdaQueryWrapper<LiVipApply> wrapper=new LambdaQueryWrapper<LiVipApply>();
        wrapper.eq(!Objects.isNull(dto.getApplyStatus()),LiVipApply::getApplyStatus,dto.getApplyStatus())
                .orderByDesc(LiVipApply::getCreateTime)
                .eq(StringUtils.isNotEmpty(dto.getSupplierId()),LiVipApply::getApplySupplierId,dto.getSupplierId())
                .like(!StringUtils.isEmpty(dto.getSupplierName()),LiVipApply::getApplySupplierName,dto.getSupplierName());
        Page<LiVipApply> page = new Page<>(dto.getPageNumber(),dto.getPageSize());

        return ResultUtil.data(applyService.page(page,wrapper));
    }

    @ApiOperation(value = "激活码审核")
    @GetMapping("/check")
    public ResultMessage<Object> checkCode(VipApplyCheck applyCheck){
        /**
         * 数据检测：1.申请人存在与否
         *      2.申请数量
         *      3.不是待审核
         */
        LambdaQueryWrapper<User>wrapper1=new LambdaQueryWrapper<>();
        wrapper1.and(q -> q.eq(User::getExtendId, applyCheck.getApplySupplierId()).or().eq(User::getId, applyCheck.getApplySupplierId()));
        User user = userService.getOne(wrapper1);
        if (Objects.isNull(user)||applyCheck.getApplyNum()<=0)
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        //开始审核
        if (applyCheck.getCheckResult()){
            //通过审核
            UpdateWrapper<LiVipApply> wrapper=new UpdateWrapper<LiVipApply>();
            wrapper.eq("id",applyCheck.getId()).set("update_by",UserContext.getCurrentId()).set("update_time",Date.from(Instant.now())).set("apply_status",2);

            applyService.update(wrapper);
            this.getVipCode(applyCheck.getApplyNum(),applyCheck.getApplySupplierId(),applyCheck.getTimeType());
            return ResultUtil.success();
        }
        if(!applyCheck.getCheckResult()){
            UpdateWrapper<LiVipApply> wrapper=new UpdateWrapper<LiVipApply>();
            wrapper.eq("id",applyCheck.getId()).set("remark",applyCheck.getRemark()).set("update_by",UserContext.getCurrentId()).set("update_time",Date.from(Instant.now())).set("apply_status",3);
            applyService.update(wrapper);
            return ResultUtil.success();
        }
        return ResultUtil.error();
    }

    //生成激活码
    private void getCodes(Integer num, User user, Integer mouthNum, ArrayList<LiVipActiveCode> codes) {
        List<String> all = codeService.getAll();
        String createId = UserContext.getCurrentId();
        HashSet<String> set = new HashSet<>(all);
        for (int i = 0; i < num; i++) {
            //重复code解决：查询出数据库已存的code并加入set集合，生成一个code就插入set，若是最后的集合size没变，就i--
            String code= user.getExtendId()+UUID.randomUUID().toString().substring(0,8);
            int n=set.size();
            set.add(code);
            if (n== set.size())
            {
                i--;
                continue;
            }
            LiVipActiveCode activeCode = LiVipActiveCode.builder()
                    .activeCode(code)
                    .supplierId(user.getId())
                    .activeStatus(0)
                    .supplierName(user.getUsername())
                    .timeType(mouthNum)
                    .createBy(createId)
                    .createTime(Date.from(Instant.now()))
                    .id(SnowFlake.getIdStr())
                    .deleteFlag("0")
                    .build();
            codes.add(activeCode);
        }
    }
}
